﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Configuration;
using Newtonsoft.Json.Linq;

namespace Treasure.Client
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        string NameValue = "";
      
        PropertyNodeItem TreeItem = null;
        bool rtxChanged = false;
       
        private void Grid_Loaded(object sender, RoutedEventArgs e)
        {
             CStatic.serviceurl = ConfigurationManager.AppSettings["ServiceApiUrl"];  //读取配置
            WinLogin winLogin = new WinLogin();
            winLogin.ShowDialog();
            if(!(bool)winLogin.DialogResult)
            {
                Environment.Exit(0);
            }
            if (CStatic.user != null)
            {
                userinfo.Text = "当前用户：" + CStatic.user.name;
            }
            Task.Factory.StartNew(()=> LoadTree()) ;
        }
        /// <summary>
        ///增加目录节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Add_Click(object sender, RoutedEventArgs e)
        {

            win_NewEdit _NewEdit = new win_NewEdit();
            _NewEdit.nameValue += namevalue;
            _NewEdit.ShowDialog();
            if (_NewEdit.DialogResult == true)
            {

                PropertyNodeItem item = TreeItem;
                var maxid = GetUriMaxID();
                if (maxid == null)
                {
                    MessageBox.Show("新增ID获取失败！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                int node_id = Convert.ToInt32(maxid) + 1;

                PropertyNodeItem node = new PropertyNodeItem()
                {
                    DisplayName = NameValue,
                    Name = NameValue,
                    id = node_id,
                    parentId = item.id,
                    IsExpanded = true,
                    IsSelected = false
                };
                item.Children.Add(node);

                    book _book = new book();
                    _book.b_id = node_id;
                    _book.b_name = NameValue;
                    _book.b_parent_id = item.id;
                    _book.b_content = " ";
                string jsonbook = Newtonsoft.Json.JsonConvert.SerializeObject(_book);
                PostUriAddNode(jsonbook);                

                LoadTree();
                item.IsExpanded = true;
                item.Children.FirstOrDefault(i => i.id == node_id).IsSelected = true;

            }
            _NewEdit.Close();
        }

        private void Edit_Click(object sender, RoutedEventArgs e)
        {
            win_NewEdit _NewEdit = new win_NewEdit();
            PropertyNodeItem item = this.tvProperties.SelectedItem as PropertyNodeItem;
            if (item == null)
                return;
            _NewEdit.SetName = item.Name;
            _NewEdit.nameValue += namevalue;
            _NewEdit.ShowDialog();
            if (_NewEdit.DialogResult == true)
            {              
                PostUriUpdateNode(item.id, NameValue);
                LoadTree();
            }
            _NewEdit.Close();
        }
        /// <summary>
        /// 编辑节点名称
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Delete_Click(object sender, RoutedEventArgs e)
        {
            PropertyNodeItem item = this.tvProperties.SelectedItem as PropertyNodeItem;
            if (item == null)
                return;
            MessageBoxResult message =  MessageBox.Show($"确定要删除{item.Name}吗？", "询问", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            PostUriDeleteNode(item.id);
            LoadTree();
        }
        /// <summary>
        /// 查找节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Select_Click(object sender, RoutedEventArgs e)
        {
            win_NewEdit _NewEdit = new win_NewEdit();

            _NewEdit.nameValue += namevalue;
            _NewEdit.ShowDialog();
            if (_NewEdit.DialogResult == true)
            {                
                List<PropertyNodeItem> nodeItems = (List<PropertyNodeItem>)tvProperties.ItemsSource;
                PropertyNodeItem nodeItem = GetFindNode(nodeItems, NameValue);
                var item = FindTviFromObjectRecursive(tvProperties, nodeItem);
                if (item != null)
                {
                    item.IsExpanded = true;
                    item.IsSelected = true;
                }             
            }
            _NewEdit.Close();
        }
        /// <summary>
        /// 刷新目录节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            //LoadTree();
            Task.Factory.StartNew(() => LoadTree());
        }


        /// <summary>
        /// 接收弹出窗的名称
        /// </summary>
        /// <param name="_name"></param>
        public void namevalue(string _name)
        {
            NameValue = _name;
        }
        /// <summary>
        ///加载树节点
        /// </summary>
        private void LoadTree()
        {         
            List<PropertyNodeItem> itemList = new List<PropertyNodeItem>();
            PropertyNodeItem node = new PropertyNodeItem()
            {
                DisplayName = "开发宝典",
                Name = "开发宝典",
                id = 0,
                parentId = 0,
                IsExpanded = true
            };

            //int pid = Convert.ToInt32(dv[0]["ParentId"].ToString());
            string jsonbooks = GetUriTreeNodeAll();
            if (jsonbooks == null)
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    MessageBox.Show("目录获取失败！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);                   
                }));
                return;
            }
            List<book> books = Newtonsoft.Json.JsonConvert.DeserializeObject<List<book>>(jsonbooks);
            ForeachPropertyNode(books,node, 0);
            itemList.Add(node);

            this.Dispatcher.Invoke(new Action(() =>
            {
                tvProperties.ItemsSource = null;
                tvProperties.ItemsSource = itemList;
            }));
           
        }
        /// <summary>
        /// 节点填充
        /// </summary>
        /// <param name="books"></param>
        /// <param name="node"></param>
        /// <param name="pid"></param>
        private void ForeachPropertyNode(List<book> books, PropertyNodeItem node, int pid)
        {
            if (books.Count > 0)
            {
                foreach (var b in books.Where(b => b.b_parent_id == pid))
                {
                    PropertyNodeItem childNodeItem = new PropertyNodeItem()
                    {
                        DisplayName = b.b_name,
                        Name = b.b_name,
                        id = b.b_id,
                        parentId = b.b_parent_id,
                        IsExpanded = true,
                        IsSelected = false
                    };
                    ForeachPropertyNode(books,childNodeItem, b.b_id);
                    node.Children.Add(childNodeItem);
                }
            }

        }
        /// <summary>
        /// 节点查找
        /// </summary>
        /// <param name="listitem"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
        private PropertyNodeItem GetPropertyNode(List<PropertyNodeItem> listitem, int pid)
        {

            if (listitem.Count > 0)
            {
                //PropertyNodeItem childNodeItem = new PropertyNodeItem();
                foreach (var b in listitem)
                {
                    if (b.id == pid)
                        return b;
                    PropertyNodeItem propertyNodeItem = GetPropertyNode(b.Children, pid);
                    if (propertyNodeItem != null && propertyNodeItem.id == pid)
                        return propertyNodeItem;
                }

            }
            return null;

        }
        /// <summary>
        /// 节点查找
        /// </summary>
        /// <param name="listitem"></param>
        /// <param name="nodename"></param>
        /// <returns></returns>
        private PropertyNodeItem GetFindNode(List<PropertyNodeItem> listitem, string nodename)
        {

            if (listitem.Count > 0)
            {
                //PropertyNodeItem childNodeItem = new PropertyNodeItem();
                foreach (var b in listitem)
                {
                    if (b.DisplayName.Contains(nodename)|| b.DisplayName== nodename)
                        return b;
                    PropertyNodeItem propertyNodeItem = GetFindNode(b.Children, nodename);
                    if (propertyNodeItem != null && (propertyNodeItem.DisplayName.Contains(nodename) || propertyNodeItem.DisplayName == nodename))
                        return propertyNodeItem;
                }

            }
            return null;

        }
        /// <summary>
        /// 树节点查找
        /// </summary>
        /// <param name="ic"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public static TreeViewItem FindTviFromObjectRecursive(ItemsControl ic, object o)
        {
            //Search for the object model in first level children (recursively)
            TreeViewItem tvi = ic.ItemContainerGenerator.ContainerFromItem(o) as TreeViewItem;
            if (tvi != null) return tvi;
            //Loop through user object models
            foreach (object i in ic.Items)
            {
                //Get the TreeViewItem associated with the iterated object model
                TreeViewItem tvi2 = ic.ItemContainerGenerator.ContainerFromItem(i) as TreeViewItem;
                tvi = FindTviFromObjectRecursive(tvi2, o);
                if (tvi != null) return tvi;
            }
            return null;
        }
        /// <summary>
        /// 节点切换， 内容编辑过会保存，显示新节点内动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tvProperties_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            PropertyNodeItem item = this.tvProperties.SelectedItem as PropertyNodeItem;
            if (item == null)
            {
                rTextBox.Document.Blocks.Clear();
                rtxChanged = false;
                return;
            }
            msg.Text = "";
            //保存文章
            if (rtxChanged && TreeItem != null)
            {               
                if (PostUriUpdateContent(TreeItem.id, MyConvert.ToBStr(MyConvert.RTF(rTextBox))) == null)
                {
                    MessageBox.Show("内容保存失败！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    rTextBox.Document.Blocks.Clear();
                    rtxChanged = false;    
                    TreeItem = item;
                    return;
                }

            }
            //切换到新文章
            string jsoncontent = GetUriFindContent(item.id);
            if (jsoncontent == null)
            {
                MessageBox.Show("获取内容失败！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                rTextBox.Document.Blocks.Clear();
                rtxChanged = false;
                TreeItem = item;
                return;
            }
            try
            {              
                MyConvert.LoadFromRTF(rTextBox, MyConvert.ToStrB(jsoncontent));
                rtxChanged = false;
            }
            catch (Exception ex)
            {
                msg.Text = ex.Message;
            }
            TreeItem = item;

        }
        /// <summary>
        /// 内容是否被编辑过
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            rtxChanged = true;
        }
        /// <summary>
        /// 全部树列表json格式
        /// </summary>
        /// <returns></returns>
        public string GetUriTreeNodeAll()
        {
            return HttpClient(CStatic.serviceurl,"Get", "treasure", "treelist");
        }
        /// <summary>
        /// 查找节点内容
        /// </summary>
        /// <param name="nodeid"></param>
        /// <returns></returns>
        public string GetUriFindContent(int nodeid)
        {
            return HttpClient(CStatic.serviceurl, "Get", "treasure", "FindContent", "id=" + nodeid);
        }
        /// <summary>
        /// book最大id
        /// </summary>
        /// <returns></returns>
        public string GetUriMaxID()
        {
            return HttpClient(CStatic.serviceurl, "Get", "treasure", "MaxID", "");
        }
        /// <summary>
        /// 添加节点远端api
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public string PostUriAddNode(string node)
        {
            return HttpClient(CStatic.serviceurl, "Post", "treasure", "AddNode", "jsonbook=" + node);
        }
        /// <summary>
        /// 最大节点id远端api
        /// </summary>
        /// <param name="nodeid"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public string PostUriUpdateContent(int nodeid, string content)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>()
            {
                {"id",nodeid.ToString()},
                {"content",content}
            };
            return HttpClientPost(CStatic.serviceurl, "treasure", "UpdateContent", dic);            
        }
        /// <summary>
        /// 更新节点名称远端api
        /// </summary>
        /// <param name="nodeid"></param>
        /// <param name="nodename"></param>
        /// <returns></returns>
        public string PostUriUpdateNode(int nodeid, string nodename)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>()
            {
                {"id",nodeid.ToString()},
                {"nodename",nodename}
            };
            return HttpClientPost(CStatic.serviceurl, "treasure", "UpdateNode", dic);
        }
        /// <summary>
        /// 删除节点远端api
        /// </summary>
        /// <param name="bid"></param>
        /// <returns></returns>
        public string PostUriDeleteNode(int bid)
        {
            return HttpClient(CStatic.serviceurl, "Post","treasure", "DeleteNode", "nodeid=" + bid);
        }

        /// <summary>
        /// 远端api调用方法
        /// </summary>
        /// <param name="url"></param>
        /// <param name="httptype"></param>
        /// <param name="controller"></param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private string HttpClient(string url,string httptype, string controller, string method, params string[] parameter)
        {
           
            Uri server = new Uri(String.Format("{0}/{1}/{2}?{3}", url,  controller, method, string.Join("&", parameter)));

            try
            {
                HttpResponseMessage response;
                if (CStatic.user != null)
                {
                    if (!HttpClientFactory.HttpClient.DefaultRequestHeaders.Contains("userid"))
                        HttpClientFactory.HttpClient.DefaultRequestHeaders.Add("userid", CStatic.user.id.ToString());
                    if (!HttpClientFactory.HttpClient.DefaultRequestHeaders.Contains("token"))
                        HttpClientFactory.HttpClient.DefaultRequestHeaders.Add("token", CStatic.user.token.ToString());
                }
                else
                {
                    HttpClientFactory.HttpClient.DefaultRequestHeaders.Remove("userid");
                    HttpClientFactory.HttpClient.DefaultRequestHeaders.Remove("token");
                }
                if (httptype == "Get")
                    response = HttpClientFactory.HttpClient.GetAsync(server).Result;
                else
                    response = HttpClientFactory.HttpClient.PostAsync(server, null).Result;
                if (response.IsSuccessStatusCode)
                {
                    return response.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        msg.Text = response.StatusCode.ToString();
                    }));
                   
                    return null;
                }
            }
            catch (Exception ex)
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    msg.Text = ex.Message;
                }));
               
            }
            return null;
        }
        /// <summary>
        ///  远端api调用方法  FormBody 方式
        /// </summary>
        /// <param name="url"></param>
        /// <param name="controller"></param>
        /// <param name="dic"></param>
        /// <returns></returns>
        private string HttpClientPost(string url, string controller, string method, Dictionary<string, string> dic)
        {

            Uri server = new Uri(String.Format("{0}/{1}/{2}", url, controller, method));

            try
            {
                //使用FormUrlEncodedContent做HttpContent
                var content = new FormUrlEncodedContent(dic);
                if (CStatic.user != null)
                {
                    if (!HttpClientFactory.HttpClient.DefaultRequestHeaders.Contains("userid"))
                        HttpClientFactory.HttpClient.DefaultRequestHeaders.Add("userid", CStatic.user.id.ToString());
                    if (!HttpClientFactory.HttpClient.DefaultRequestHeaders.Contains("token"))
                        HttpClientFactory.HttpClient.DefaultRequestHeaders.Add("token", CStatic.user.token.ToString());
                }
                else
                {
                    HttpClientFactory.HttpClient.DefaultRequestHeaders.Remove("userid");
                    HttpClientFactory.HttpClient.DefaultRequestHeaders.Remove("token");
                }
                var response = HttpClientFactory.HttpClient.PostAsync(server, content).Result;
                if (response.IsSuccessStatusCode)
                {
                    return response.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        msg.Text = response.StatusCode.ToString();
                    }));
                    return null;
                }

            }
            catch (Exception ex)
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    msg.Text = ex.Message;
                }));
                
            }
            return null;
        }

        private void Userinfo_MouseDown(object sender, MouseButtonEventArgs e)
        {

        }
    }
    }
